package com.loubobooo.personal.blog.service.impl;

import com.google.common.collect.Lists;
import com.loubobooo.personal.blog.common.Const;
import com.loubobooo.personal.blog.mapper.ArticleMapper;
import com.loubobooo.personal.blog.mapper.TagMapper;
import com.loubobooo.personal.blog.mapper.UserMapper;
import com.loubobooo.personal.blog.mapper.custom.*;
import com.loubobooo.personal.blog.entity.Article;
import com.loubobooo.personal.blog.entity.Tag;
import com.loubobooo.personal.blog.entity.User;
import com.loubobooo.personal.blog.entity.vo.*;
import com.loubobooo.personal.blog.page.PageResult;
import com.loubobooo.personal.blog.service.ArticleService;
import com.loubobooo.personal.blog.util.Functions;
import com.loubobooo.personal.blog.util.RedisPoolUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 用户管理
 */
@Service public class ArticleServiceImpl implements ArticleService {
    @Autowired private ArticleMapperCustom articleMapperCustom;

    @Autowired private ArticleMapper articleMapper;

    @Autowired private CategoryMapperCustom categoryMapperCustom;

    @Autowired private TagMapper tagMapper;

    @Autowired private UserMapper userMapper;

    @Autowired private CommentMapperCustom commentMapperCustom;

    @Override public Integer countArticle(Integer status) {
        Integer articleCount = articleMapperCustom.countArticle(status);
        return articleCount;
    }

    @Override public Integer countArticleComment(Integer status) {
        Integer commentCount = articleMapperCustom.countArticleComment(status);
        return commentCount;
    }

    @Override public Integer countArticleView(Integer status) {
        Integer viewCount = articleMapperCustom.countArticleView(status);
        return viewCount;
    }

    /**
     * @return 返回类型
     * @Description: TODO:等待修改的内容
     * @date 2018/3/23 15:42
     */
    @Override public List<ArticleListVo> listArticle(Integer status) {
        List<ArticleListVo> articleListVoList = new ArrayList<ArticleListVo>();

        //获得文章列表信息和分页信息
        List<ArticleVO> articleVOList = articleMapperCustom.listArticle(status);

        //获得分类信息
        for (int i = 0; i < articleVOList.size(); i++) {
            ArticleListVo articleListVo = new ArticleListVo();

            //1、将文章信息装到 articleListVoList 中
            ArticleVO articleVO = articleVOList.get(i);
            articleListVo.setArticleVO(articleVO);

            //2、将分类信息装到 articleListVoList 中
            List<CategoryVO> categoryVOList = new ArrayList<CategoryVO>();
            Integer parentCategoryId = articleVOList.get(i).getArticleParentCategoryId();
            Integer childCategoryId = articleVOList.get(i).getArticleChildCategoryId();
            CategoryVO categoryVO = categoryMapperCustom.getCategoryById(1, parentCategoryId);
            CategoryVO categoryVO2 = categoryMapperCustom.getCategoryById(1, childCategoryId);
            if (categoryVO != null) {
                categoryVOList.add(categoryVO);
            }
            if (categoryVO2 != null) {
                categoryVOList.add(categoryVO2);
            }
            articleListVo.setCategoryVOList(categoryVOList);

            //3、获得标签信息
            List<TagVO> tagVOList = new ArrayList<TagVO>();
            String tagIds = articleVOList.get(i).getArticleTagIds();
            //防止该文章没有分类，空指针
            if (StringUtils.isNotBlank(tagIds)) {
                String[] tagId = tagIds.split(",");
                for (int j = 0; j < tagId.length; j++) {
                    Tag tag = tagMapper.selectByPrimaryKey(Integer.valueOf(tagId[j]));
                    //防止标签不存在，被删除
                    if (tag != null) {
                        TagVO tagVO = new TagVO();
                        BeanUtils.copyProperties(tag, tagVO);
                        tagVOList.add(tagVO);
                    }
                }
            }
            articleListVo.setTagVOList(tagVOList);

            //4、获得作者信息
            User user = userMapper.selectByPrimaryKey(articleVO.getArticleUserId());
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(user, userVO);
            articleListVo.setUserVO(userVO);

            articleListVoList.add(articleListVo);
        }
        return articleListVoList;
    }

    @Override public ArticleVO getArticleById(Integer status, Integer id) {
        return articleMapperCustom.getArticleById(status, id);
    }

    @Override public void updateArticle(Integer id, Article article) {
        //添加业务校验，通常在service接口对关键
        article.setArticleId(id);
        articleMapper.updateByPrimaryKeySelective(article);
        //更新的时候需要删除redis缓存，全页缓存可以不删除
        RedisPoolUtil.del(Const.REDIS_KEY.ALL_ARTICLE);
        RedisPoolUtil.del(Const.REDIS_KEY.ARTICLE_DETAIL_SHOW + "_" + id);
    }

    @Override public void deleteArticleBatch(Integer[] ids) {
        for (int i = 0; i < ids.length; i++) {
            articleMapper.deleteByPrimaryKey(ids[i]);
            //这里可删可不删除，id是自增保证了不会重复
            // RedisPoolUtil.del(Const.REDIS_KEY.ARTICLE_DETAIL_SHOW + "_" + i);
        }
        // 同时删除redis缓存
        RedisPoolUtil.del(Const.REDIS_KEY.ALL_ARTICLE);
    }

    @Override public void deleteArticle(Integer id) {
        articleMapper.deleteByPrimaryKey(id);
        //这里可删可不删除，id是自增保证了不会重复
        // RedisPoolUtil.del(Const.REDIS_KEY.ARTICLE_DETAIL_SHOW + "_" + i);
        // 同时删除redis缓存
        RedisPoolUtil.del(Const.REDIS_KEY.ALL_ARTICLE);
    }

    /**
     * @return 返回类型
     * @Description: TODO:分页显示文章列表
     * @date 2018/3/23 16:20
     */
    @Override public List<ArticleListVo> listArticleByPage(Integer status, Integer pageNo, Integer pageSize) {
        List<ArticleListVo> articleListVoList = new ArrayList<ArticleListVo>();

        //获得文章列表信息和分页信息
        PageResult pageResult = null;
        int totalCount = articleMapperCustom.countArticle(status);
        if (pageNo != null) {
            pageResult = new PageResult(totalCount, pageNo, pageSize);
        }
        else {
            pageResult = new PageResult(totalCount, 1, pageSize);
        }
        List<ArticleVO> articleVOList = articleMapperCustom
                .listArticleByPage(status, pageResult.getStartPos(), pageSize);
        //获得分类信息
        for (int i = 0; i < articleVOList.size(); i++) {
            ArticleListVo articleListVo = new ArticleListVo();

            //1、将文章信息装到 articleListVoList 中
            ArticleVO articleVO = articleVOList.get(i);
            articleListVo.setArticleVO(articleVO);

            //2、将分类信息装到 articleListVoList 中
            List<CategoryVO> categoryVOList = new ArrayList<CategoryVO>();
            Integer parentCategoryId = articleVOList.get(i).getArticleParentCategoryId();
            Integer childCategoryId = articleVOList.get(i).getArticleChildCategoryId();
            CategoryVO categoryVO = categoryMapperCustom.getCategoryById(status, parentCategoryId);
            CategoryVO categoryVO2 = categoryMapperCustom.getCategoryById(status, childCategoryId);
            if (categoryVO != null) {
                categoryVOList.add(categoryVO);
            }
            if (categoryVO2 != null) {
                categoryVOList.add(categoryVO2);
            }
            articleListVo.setCategoryVOList(categoryVOList);

            //3、获得标签信息
            List<TagVO> tagVOList = new ArrayList<TagVO>();
            String tagIds = articleVOList.get(i).getArticleTagIds();
            List<Integer> idList = Lists.newArrayList();
            //防止该文章没有分类，空指针
            if (StringUtils.isNotBlank(tagIds)) {
                String[] tagId = tagIds.split(",");
                for (int j = 0; j < tagId.length; j++) {
                    idList.add(Integer.valueOf(tagId[j]));
                }
                // 减少查询数据库的次数
                List<Tag> tagList = tagMapper.selectByIdList(idList);
                for (Tag tagItem : tagList) {
                    //防止标签不存在，被删除
                    if (tagItem != null) {
                        TagVO tagVO = new TagVO();
                        BeanUtils.copyProperties(tagItem, tagVO);
                        tagVOList.add(tagVO);
                    }
                }
            }
            articleListVo.setTagVOList(tagVOList);

            //4、获得作者信息
            User user = userMapper.selectByPrimaryKey(articleVO.getArticleUserId());
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(user, userVO);
            articleListVo.setUserVO(userVO);

            articleListVoList.add(articleListVo);
        }

        if (CollectionUtils.isNotEmpty(articleListVoList)) {
            //4、将Page信息存储在第一个元素中
            articleListVoList.get(0).setPageResult(pageResult);
        }
        return articleListVoList;
    }

    /**
     * @return 返回类型
     * @Description: TODO:文章详情页面显示
     * @date 2018/3/23 16:20
     */
    @Override public ArticleDetailVo getArticleDetailById(Integer id) {
        ArticleDetailVo articleDetailVo = new ArticleDetailVo();

        //1、获得文章信息
        ArticleVO articleVO = articleMapperCustom.getArticleById(1, id);
        if (articleVO == null) {
            return null;
        }
        articleDetailVo.setArticleVO(articleVO);

        //2、将分类信息装到 articleListVoList 中
        List<CategoryVO> categoryVOList = new ArrayList<CategoryVO>();
        Integer cate = articleVO.getArticleParentCategoryId();
        Integer cate2 = articleVO.getArticleChildCategoryId();
        CategoryVO categoryVO = categoryMapperCustom.getCategoryById(1, cate);
        CategoryVO categoryVO2 = categoryMapperCustom.getCategoryById(1, cate2);
        if (categoryVO != null) {
            categoryVOList.add(categoryVO);
        }
        if (categoryVO2 != null) {
            categoryVOList.add(categoryVO2);
        }
        articleDetailVo.setCategoryVOList(categoryVOList);

        //3、获得文章的标签
        String tagIds = articleVO.getArticleTagIds();
        List<TagVO> tagVOList = new ArrayList<TagVO>();
        List<Integer> idList = Lists.newArrayList();
        if (StringUtils.isNotBlank(tagIds)) {
            String[] tags = tagIds.split(",");
            for (int i = 0; i < tags.length; i++) {
                idList.add(Integer.valueOf(tags[i]));
            }
            // 减少查询数据库的次数
            List<Tag> tagList = tagMapper.selectByIdList(idList);
            for (Tag tagItem : tagList)
                if (tagItem != null) {
                    TagVO tagVO = new TagVO();
                    BeanUtils.copyProperties(tagItem, tagVO);
                    tagVOList.add(tagVO);
                }
        }
        articleDetailVo.setTagVOList(tagVOList);

        //4、获得文章的作者
        Integer userId = articleVO.getArticleUserId();
        User user = userMapper.selectByPrimaryKey(userId);
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        articleDetailVo.setUserVO(userVO);

        //5、获取评论信息列表
        List<CommentVO> commentVOList = commentMapperCustom.listCommentByArticleId(1, id);
        //给每个评论用户添加头像
        for (int i = 0; i < commentVOList.size(); i++) {
            String avatar = Functions.getGravatar(commentVOList.get(i).getCommentAuthorEmail());
            commentVOList.get(i).setCommentAuthorAvatar(avatar);
        }
        articleDetailVo.setCommentVOList(commentVOList);

        return articleDetailVo;
    }

    /**
     * @return 返回类型
     * @Description: TODO:文章查询结果分页
     * @date 2018/3/23 16:21
     */
    @Override public List<ArticleSearchVo> listSearchResultByPage(Integer status, HttpServletRequest request,
            Model model, Integer pageNo, Integer pageSize, String query) {
        PageResult pageResult = null;
        List<ArticleVO> articleVOList = new ArrayList<ArticleVO>();
        int totalCount = articleMapperCustom.getSearchResultCount(status, query);

        if (pageNo != null) {
            pageResult = new PageResult(totalCount, pageNo, pageSize);
            articleVOList = this.articleMapperCustom
                    .listSearchResultByPage(status, query, pageResult.getStartPos(), pageResult.getPageSize());
        }
        else {
            pageResult = new PageResult(totalCount, 1, pageSize);
            articleVOList = this.articleMapperCustom
                    .listSearchResultByPage(status, query, pageResult.getStartPos(), pageResult.getPageSize());
        }

        List<ArticleSearchVo> articleSearchVoList = new ArrayList<ArticleSearchVo>();

        //查询结果条数为0，下面的不执行，防止空指针
        if (totalCount != 0) {
            for (int i = 0; i < articleVOList.size(); i++) {
                ArticleSearchVo articleSearchVo = new ArticleSearchVo();

                //1、将文章信息装到 articleListVoList 中
                ArticleVO articleVO = articleVOList.get(i);
                articleSearchVo.setArticleVO(articleVO);

                //2、将分类信息装到 articleListVoList 中
                List<CategoryVO> categoryVOList = new ArrayList<CategoryVO>();
                Integer cate = articleVOList.get(i).getArticleParentCategoryId();
                Integer cate2 = articleVOList.get(i).getArticleChildCategoryId();
                CategoryVO categoryVO = categoryMapperCustom.getCategoryById(status, cate);
                CategoryVO categoryVO2 = categoryMapperCustom.getCategoryById(status, cate2);
                if (categoryVO != null) {
                    categoryVOList.add(categoryVO);
                }
                if (categoryVO2 != null) {
                    categoryVOList.add(categoryVO2);
                }
                articleSearchVo.setCategoryVOList(categoryVOList);

                //3、获得标签信息
                List<TagVO> tagVOList = new ArrayList<TagVO>();
                String tagIds = articleVOList.get(i).getArticleTagIds();
                List<Integer> idList = Lists.newArrayList();
                if (StringUtils.isNotBlank(tagIds)) {
                    String[] tagId = tagIds.split(",");
                    for (int j = 0; j < tagId.length; j++) {
                        idList.add(Integer.valueOf(tagId[j]));
                    }
                    // 减少查询数据库的次数
                    List<Tag> tagList = tagMapper.selectByIdList(idList);
                    for (Tag tagItem : tagList) {
                        if (tagItem != null) {
                            TagVO tagVO = new TagVO();
                            BeanUtils.copyProperties(tagItem, tagVO);
                            tagVOList.add(tagVO);
                        }
                    }
                }
                articleSearchVo.setTagVOList(tagVOList);

                //4、获得作者信息
                User user = userMapper.selectByPrimaryKey(articleVO.getArticleUserId());
                UserVO userVO = new UserVO();
                BeanUtils.copyProperties(user, userVO);
                articleSearchVo.setUserVO(userVO);

                articleSearchVoList.add(articleSearchVo);
            }
        }
        else {
            //不执行的话，也要创建一个元素，存储分页信息和查询关键字
            ArticleSearchVo articleSearchVo = new ArticleSearchVo();
            articleSearchVoList.add(articleSearchVo);
        }
        //5、page信息存储在第一个元素中
        articleSearchVoList.get(0).setPageResult(pageResult);

        //6、将查询的关键词存储到第一个元素
        articleSearchVoList.get(0).setQuery(query);

        return articleSearchVoList;
    }

    /**
     * @return 返回类型
     * @Description: 相似文章获取
     * @date 2018/3/23 16:22
     */
    @Override public List<ArticleVO> listArticleWithSameCategory(Integer status, Integer parentCategoryId,
            Integer childCategoryId, Integer limit) {
        List<ArticleVO> similarArticleList = articleMapperCustom
                .listArticleWithSameCategory(status, parentCategoryId, childCategoryId, limit);
        return similarArticleList;
    }

    //访问量从多到少的文章获取
    @Override public List<ArticleVO> listArticleByViewCount(Integer status, Integer limit) {
        List<ArticleVO> mostViewArticleList = articleMapperCustom.listArticleByViewCount(status, limit);
        return mostViewArticleList;
    }

    /**
     * @return 返回类型
     * @Description: 获取下一篇文章
     * @date 2018/3/23 16:22
     */
    @Override public ArticleVO getAfterArticle(Integer status, Integer id) {
        ArticleVO articleVO = articleMapperCustom.getAfterArticle(status, id);
        return articleVO;
    }

    //获取上一篇文章
    @Override public ArticleVO getPreArticle(Integer status, Integer id) {
        ArticleVO articleVO = articleMapperCustom.getPreArticle(status, id);
        return articleVO;
    }

    /**
     * @return 返回类型
     * @Description: 获得随机文章
     * @date 2018/3/23 16:22
     */
    @Override public List<ArticleVO> listRandomArticle(Integer status, Integer limit) {
        List<ArticleVO> articleCustomsList = articleMapperCustom.listRandomArticle(status, limit);
        return articleCustomsList;
    }

    /**
     * @return 返回类型
     * @Description: 获得热评文章列表
     * @date 2018/3/23 16:21
     */
    @Override public List<ArticleVO> listArticleByCommentCount(Integer status, Integer limit) {
        List<ArticleVO> articleCustomsList = articleMapperCustom.listArticleByCommentCount(status, limit);
        return articleCustomsList;
    }

    /**
     * @return 返回类型
     * @Description: 添加文章
     * @date 2018/3/23 16:21
     */
    @Override public void insertArticle(Article article) {

        Date date = new Date();
        article.setArticlePostTime(date);
        article.setArticleUpdateTime(date);
        article.setArticleIsComment(1);
        article.setArticleViewCount(0);
        article.setArticleLikeCount(0);
        article.setArticleCommentCount(0);
        article.setArticleOrder(1);

        articleMapper.insertSelective(article);
        // 同时删除redis缓存
        RedisPoolUtil.del(Const.REDIS_KEY.ALL_ARTICLE);
    }

    /**
     * @return 返回类型
     * @Description: 统计某个分类的文章数
     * @date 2018/3/23 16:21
     */
    @Override public Integer countArticleWithCategory(Integer status, Integer id) {
        int count = articleMapperCustom.countArticleByCategory(status, id);
        return count;
    }

    //统计某个标签的文章数
    @Override public Integer countArticleWithTag(Integer status, Integer id) {
        int count = articleMapperCustom.countArticleByTag(status, id);
        return count;
    }

    @Override public void updateCommentCount(Integer articleId) {
        articleMapperCustom.updateCommentCount(articleId);
    }

    @Override public ArticleVO getLastUpdateArticle() {
        ArticleVO articleVO = articleMapperCustom.getLastUpdateArticle();
        return articleVO;
    }

}
